package com.sql.compare.service.impl;

import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.sql.compare.dto.ResultDTO;
import com.sql.compare.entity.Column;
import com.sql.compare.entity.SqlCompare;
import com.sql.compare.mapper.SqlCompareMapper;
import com.sql.compare.service.SqlCompareService;
import com.sql.compare.utils.SqlFileCompareUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class SqlCompareServiceImpl implements SqlCompareService {
    @Autowired
    private SqlCompareMapper sqlCompareMapper;

    @Override
    public ResultDTO<String> databaseCompare(SqlCompare sqlCompare) {
        Map<String, List<Column>> from = getColumn(sqlCompare.getPoolNameFrom(), sqlCompare.getDatabaseFrom());
        Map<String, List<Column>> to = getColumn(sqlCompare.getPoolNameTo(), sqlCompare.getDatabaseTo());
        String differenceList = SqlFileCompareUtils.getDifferenceList(from, to);
        log.info("{}",differenceList);
        return new ResultDTO<>(0, "success",differenceList);
    }

    @Override
    public ResultDTO<String> tableCompare(SqlCompare sqlCompare) {
        List<Column> from = getColumn(sqlCompare.getPoolNameFrom(), sqlCompare.getDatabaseFrom(),sqlCompare.getTableFrom());
        List<Column> to = getColumn(sqlCompare.getPoolNameTo(), sqlCompare.getDatabaseTo(),sqlCompare.getTableTo());
        List<String> fieldList = SqlFileCompareUtils.getDifferenceFieldList(sqlCompare.getTableFrom() + "-" + sqlCompare.getTableTo(), from, to);
        StringBuilder sb = new StringBuilder();
        sb.append("-----------共变化 ").append(fieldList.size()).append( "处，具体如下-------").append("\n");
        for (int i = 0; i < fieldList.size(); i++) {
            sb.append(String.format("【%s】%s", (i + 1), fieldList.get(i))).append("\n");
        }
        log.info("{}",sb.toString());
        return new ResultDTO<>(0, "success",sb.toString());
    }

    @Override
    public ResultDTO<String> indexCompare(SqlCompare sqlCompare) {
        Map<String, List<Column>> from = getIndex(sqlCompare.getPoolNameFrom(), sqlCompare.getDatabaseFrom());
        Map<String, List<Column>> to = getIndex(sqlCompare.getPoolNameTo(), sqlCompare.getDatabaseTo());
        String difference = SqlFileCompareUtils.getDifferenceIndexList(from, to);
        log.info("{}",difference);
        return new ResultDTO<>(0, "success",difference);
    }

    @Override
    public ResultDTO<String> contentCompare(SqlCompare sqlCompare) {
        List<String> from = getContent(sqlCompare.getPoolNameFrom(), sqlCompare.getDatabaseFrom(),sqlCompare.getTableFrom(),sqlCompare.getUniqueValues().split(","));
        List<String> to = getContent(sqlCompare.getPoolNameTo(), sqlCompare.getDatabaseTo(),sqlCompare.getTableTo(),sqlCompare.getUniqueValues().split(","));
        List<String> differenceList = SqlFileCompareUtils.getDifferenceContentList(sqlCompare.getTableFrom(), sqlCompare.getTableTo(), from, to);
        if (differenceList.isEmpty()) {
            log.info("表和索引无变化");
            return new ResultDTO<>(0, "success","表和索引无变化");
        }
        int size = differenceList.size();
        StringBuilder sb = new StringBuilder();
        sb.append("-----------共变化 ").append(differenceList.size()).append( "处，具体如下-------").append("\n");
        for (int i = 0; i < size; i++) {
            sb.append(String.format("【%s】%s", (i + 1), differenceList.get(i))).append("\n");
        }
        log.info("{}",sb.toString());
        return new ResultDTO<>(0, "success",sb.toString());
    }

    /**
     * 获取数据库下所有表字段
     * @author xuepeng
     * @date 2024/1/31 10:08
     */
    private Map<String, List<Column>> getColumn(String dataSource, String databaseName){
        Map<String, List<Column>> map = new HashMap<>();
        DynamicDataSourceContextHolder.push(dataSource);
        List<String> tableList = sqlCompareMapper.getTableByDataBaseName(databaseName);
        for (String tableName : tableList) {
            List<Column> tableColumn = sqlCompareMapper.getTableColumn(databaseName, tableName);
            map.put(tableName,tableColumn);
        }
        DynamicDataSourceContextHolder.poll();
        return map;
    }

    /**
     * 获取表字段
     * @return null
     * @author xuepeng
     * @date 2024/1/26 16:01
     */
    private List<Column> getColumn(String dataSource,String databaseName,String tableName){
        DynamicDataSourceContextHolder.push(dataSource);
        List<Column> tableColumn = sqlCompareMapper.getTableColumn(databaseName, tableName);
        DynamicDataSourceContextHolder.poll();
        return tableColumn;
    }

    /**
     * 获取数据库下所有表索引
     * @author xuepeng
     * @date 2024/1/31 10:09
     */
    private Map<String, List<Column>> getIndex(String dataSource,String databaseName){
        Map<String, List<Column>> map = new HashMap<>();
        DynamicDataSourceContextHolder.push(dataSource);
        List<String> tableList = sqlCompareMapper.getTableByDataBaseName(databaseName);
        for (String tableName : tableList) {
            List<Column> keyColumn = sqlCompareMapper.getIndex(databaseName, tableName);
            map.put(tableName,keyColumn);
        }
        DynamicDataSourceContextHolder.poll();
        return map;
    }
    /**
     * 获取表索引
     * @author xuepeng
     * @date 2024/1/31 10:09
     */
    private List<Column> getIndex(String dataSource,String databaseName,String tableName){
        DynamicDataSourceContextHolder.push(dataSource);
        List<Column> indexColumn = sqlCompareMapper.getIndex(databaseName, tableName);
        DynamicDataSourceContextHolder.poll();
        return indexColumn;
    }
    /**
     * 获取表唯一主键内容，多个主键内容是要”-“进行分割
     * @author xuepeng
     * @date 2024/1/31 10:12
     */
    private List<String> getContent(String dataSource,String databaseName,String tableName,String... arr){
        DynamicDataSourceContextHolder.push(dataSource);
        List<String> content = sqlCompareMapper.getContent(databaseName, tableName, Arrays.asList(arr));
        DynamicDataSourceContextHolder.poll();
        return content;
    }

}
